home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
xlib04.zip
/
XCBITMAP.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-11-12
|
13KB
|
423 lines
;-----------------------------------------------------------------------
; MODULE XCBITMAP
; This module was written by Matthew MacKenzie
; matm@eng.umd.edu
;
; Compiled bitmap functions all MODE X 256 Color resolutions
;
; Compile with Tasm.
; C callable.
;
; egg@dstos3.dsto.gov.au
; teg@bart.dsto.gov.au
;-----------------------------------------------------------------------
include xlib.inc
include xcbitmap.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; _x_compile_bitmap
;
; Compile a linear bitmap to generate machine code to plot it
; at any required screen coordinates FAST. Faster than blits
; using planar bitmaps as in module XPBIITMAP
;
; C near-callable as:
; int x_compile_bitmap (WORD logical_screen_width,
; char far * bitmap, char far * output);
;
; The logical width is in bytes rather than pixels.
;
; All four main registers are totaled.
;
; The source linear bitmaps have the following structure:
;
; BYTE 0 The bitmap width in pixels range 1..255
; BYTE 1 The bitmap height in rows range 1..255
; BYTE 2..n The width*height bytes of the bitmap in
; cloumn row order
;
; The returned value is the size of the compiled bitmap, in bytes.
; accessory macros to save typing (what else?)
Emitb macro arg
mov byte ptr es:[di],&arg&
inc di
endm
Emitw macro arg
mov word ptr es:[di],&arg&
add di,2
endm
; opcodes emitted by _x_compile_sprite
ROL_AL equ 0c0d0h ; rol al
SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8
STORE_8 equ 084c6h ; mov [si]+disp16, imm8
SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16
STORE_16 equ 084c7h ; mov [si]+disp16, imm16
ADC_SI_IMMED equ 0d683h ; adc si,imm8
OUT_AL equ 0eeh ; out dx,al
RETURN equ 0cbh ; ret
.data
align 2
ColumnMask db 011h,022h,044h,088h
.code
align 2
_x_compile_bitmap proc
ARG logical_width:word,bitmap:dword,output:dword
LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
push bp
mov bp, sp ; caller's stack frame
sub sp,LocalStk ; local space
push si
push di
push ds
mov word ptr [scanx],0
mov word ptr [scany],0
mov word ptr [outputx],0
mov word ptr [outputy],0
mov word ptr [column],0
mov word ptr [set_column],0
lds si,[bitmap] ; 32-bit pointer to source bitmap
les di,[output] ; 32-bit pointer to destination stream
lodsb ; load width byte
xor ah,ah ; convert to word
mov [bwidth],ax ; save for future reference
mov bl,al ; copy width byte to bl
lodsb ; load height byte. Is word since ah=0
mul bl ; mult height word by width byte
mov [input_size],ax ; giving pixel total and save
@@MainLoop:
mov bx,[scanx] ; position in original bitmap
add bx,[scany]
mov al,[si+bx] ; get pixel
or al,al ; skip empty pixels
jnz @@NoAdvance
jmp @@Advance
@@NoAdvance:
mov dx,[set_column]
cmp dx,[column]
je @@SameColumn
@@ColumnLoop:
Emitw ROL_AL ; emit code to adjust sprite
Emitw ADC_SI_IMMED
Emitb 0
inc dx
cmp dx,[column]
jl @@ColumnLoop
Emitb OUT_AL ; emit code to set VGA mask for new column
mov [set_column],dx
@@SameColumn:
mov dx,[outputy] ; calculate output position
add dx,[outputx]
sub dx,128
add word ptr [scanx],4
mov cx,[scanx] ; within four pixels of right edge?
cmp cx,[bwidth]
jge @@OnePixel
inc word ptr [outputx]
mov ah,[si+bx+4] ; get second pixel
or ah,ah
jnz @@TwoPixels
@@OnePixel:
cmp dx,127 ; can we use shorter form?
jg @@OnePixLarge
cmp dx,-128
jl @@OnePixLarge
Emitw SHORT_STORE_8
Emitb dl ; 8-bit position in output
jmp @@EmitOnePixel
@@OnePixLarge:
Emitw STORE_8
Emitw dx ; position in output
@@EmitOnePixel:
Emitb al
jmp short @@Advance
@@TwoPixels:
cmp dx,127
jg @@TwoPixLarge
cmp dx,-128
jl @@TwoPixLarge
Emitw SHORT_STORE_16
Emitb dl ; 8-bit position in output
jmp @@EmitTwoPixels
@@TwoPixLarge:
Emitw STORE_16
Emitw dx ; position in output
@@EmitTwoPixels:
Emitw ax
@@Advance:
inc word ptr [outputx]
mov ax,[scanx]
add ax,4
cmp ax,[bwidth]
jl @@AdvanceDone
mov dx,[outputy]
add dx,[logical_width]
mov cx,[scany]
add cx,[bwidth]
cmp cx,[input_size]
jl @@NoNewColumn
inc word ptr [column]
mov cx,[column]
cmp cx,4
je @@Exit ; Column 4: there is no column 4.
xor cx,cx ; scany and outputy are 0 again for
mov dx,cx ; the new column
@@NoNewColumn:
mov [outputy],dx
mov [scany],cx
mov word ptr [outputx],0
mov ax,[column]
@@AdvanceDone:
mov [scanx],ax
jmp @@MainLoop
@@Exit:
Emitb RETURN
mov ax,di
sub ax,word ptr [output] ; size of generated code
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_x_compile_bitmap endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; _x_sizeof_compiled_bitmap
;
; This function follows the same algorithm as the one above,
; but does not generate a new object. Its sole purpose is to
; determine how much space the compiled bitmap will require.
;
; C near-callable as:
; int x_sizeof_compiled_bitmap (WORD logical_screen_width,
; char far * bitmap);
;
; The logical width is in bytes rather than pixels.
;
; All four main registers are totaled.
;
; The source linear bitmaps have the following structure:
;
; BYTE 0 The bitmap width in pixels range 1..255
; BYTE 1 The bitmap height in rows range 1..255
; BYTE 2..n The width*height bytes of the bitmap in
; cloumn row order
;
; The returned value is the size of the compiled bitmap, in bytes.
align 2
_x_sizeof_compiled_bitmap proc
ARG logical_width:word,bitmap:dword
LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk
push bp
mov bp, sp ; caller's stack frame
sub sp,LocalStk ; local space
push si
push di
push ds
mov word ptr [scanx],0
mov word ptr [scany],0
mov word ptr [outputx],0
mov word ptr [outputy],0
mov word ptr [column],0
mov word ptr [set_column],0
lds si,[bitmap] ; 32-bit pointer to source bitmap
mov di, 0 ; initial size is nada
lodsb ; load width byte
xor ah,ah ; convert to word
mov [bwidth],ax ; save for future reference
mov bl,al ; copy width byte to bl
lodsb ; load height byte. Is word since ah=0
mul bl ; mult height word by width byte
mov [input_size],ax ; giving pixel total and save
@@MainLoop:
mov bx,[scanx] ; position in original bitmap
add bx,[scany]
mov al,[si+bx] ; get pixel
or al,al ; skip empty pixels
jnz @@NoAdvance
jmp @@Advance
@@NoAdvance:
mov dx,[set_column]
cmp dx,[column]
je @@SameColumn
@@ColumnLoop:
add di, 5 ; size of code to adjust sprite
; for new column
inc dx
cmp dx,[column]
jl @@ColumnLoop
inc di ; size of code to set VGA mask
mov [set_column],dx
@@SameColumn:
mov dx,[outputy] ; calculate output position
add dx,[outputx]
sub dx,128
add word ptr [scanx],4
mov cx,[scanx] ; within four pixels of right edge?
cmp cx,[bwidth]
jge @@OnePixel
inc word ptr [outputx]
mov ah,[si+bx+4] ; get second pixel
or ah,ah
jnz @@TwoPixels
@@OnePixel:
cmp dx,127 ; can we use shorter form?
jg @@OnePixLarge
cmp dx,-128
jl @@OnePixLarge
add di, 3 ; 8-bit position in output
jmp @@EmitOnePixel
@@OnePixLarge:
add di, 4 ; size of position in output
@@EmitOnePixel:
inc di
jmp short @@Advance
@@TwoPixels:
cmp dx,127
jg @@TwoPixLarge
cmp dx,-128
jl @@TwoPixLarge
add di, 3 ; 8-bit position in output
jmp @@EmitTwoPixels
@@TwoPixLarge:
add di, 4 ; position in output
@@EmitTwoPixels:
add di, 2
@@Advance:
inc word ptr [outputx]
mov ax,[scanx]
add ax,4
cmp ax,[bwidth]
jl @@AdvanceDone
mov dx,[outputy]
add dx,[logical_width]
mov cx,[scany]
add cx,[bwidth]
cmp cx,[input_size]
jl @@NoNewColumn
inc word ptr [column]
mov cx,[column]
cmp cx,4
je @@Exit ; Column 4: there is no column 4.
xor cx,cx ; scany and outputy are 0 again for
mov dx,cx ; the new column
@@NoNewColumn:
mov [outputy],dx
mov [scany],cx
mov word ptr [outputx],0
mov ax,[column]
@@AdvanceDone:
mov [scanx],ax
jmp @@MainLoop
@@Exit:
inc di
mov ax,di ; size of generated code
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_x_sizeof_compiled_bitmap endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; _x_put_cbitmap
;
; Displays a compiled bitmap generated by x_compile_bitmap at given
; coordinates, on a given screen page.
;
; C near-callable as:
; void x_put_cbitmap (int XPos, int YPos,
; unsigned int PageOffset, char far * Sprite);
; ax, bx, cx, and dx are squashed like insignificant insects.
align 2
_x_put_cbitmap proc
ARG XPos:word,YPos:word,PageOffset:word,Sprite:dword
push bp
mov bp, sp
push si
push ds
mov ax,[_ScrnLogicalByteWidth] ; global Xlib variable
mul word ptr [YPos] ; height in bytes
mov si,[XPos]
mov bx,si
shr bx,1
shr bx,1 ; width in VGA planes
add bx,ax
add bx,[PageOffset] ; (YPos * screen width) +
add bx,128 ; ==> (Xpos / 4) + page base - 128
mov dx,SC_INDEX
mov al,MAP_MASK
out dx,al
inc dx ; ready to send out other masks as bytes
and si,3 ; XPos & 3 = column
mov al,ColumnMask[si]
out dx,al
mov si,bx ; position of upper-left corner of sprite
mov bx,SCREEN_SEG
mov ds,bx ; We do this so the compiled shape won't need
; segment overrides.
call dword ptr [Sprite] ; the business end of the routine
pop ds
pop si
pop bp
ret
_x_put_cbitmap endp
end